﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Xml;
using System.Xml.Serialization;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity;
using T.FAS.Runtime.Metadata.SPI;
using T.FAS.Page.MetaData.Dao;
using T.FAS.Runtime.Metadata.Entity.Page;
using Teld.Core.ServiceGateway.Client;
using Teld.Core.ServiceGateway.ClientExtension;

namespace T.FAS.Runtime.Metadata.Plugin
{
    public class FasMenuRTPManager : AbsMetaDataManager, IMetaDataManager
    {
        /// <summary>
        /// 为了单元测试
        /// </summary>
        public static bool IsDebug { get; set; } = false;
        readonly MenuLogic menuLogic = new MenuLogic();
        public MetaDataCompileResult Compile(IList<IMetaDataContent> metadatas)
        {
            return new MetaDataCompileResult();
        }

        public ConflictMessage ConflictCheck(List<IMetaDataContent> releasedMetaData, IMetaDataContent releaseingMetaData)
        {
            return new ConflictMessage();
        }

        public void Delete(IMetaDataContent metaData)
        {
            menuLogic.DeleteMenu(metaData.MetaDataID);
        }

        public IMetaDataContent DeserializeObject(string metaDataString, MetadataSerializeType serializeType)
        {
            if (string.IsNullOrEmpty(metaDataString))
            {
                throw new ArgumentException($"“{nameof(metaDataString)}”不能为 null 或空。", nameof(metaDataString));
            }

            IMetaDataContent metaDataContent = JsonConvert.DeserializeObject<FasMenu>(metaDataString);
            if (metaDataContent == null)
            {
                throw new FasException(FasMenuExceptionCode.DeserializeFailed, $"反序列化FasMenu元数据失败,json:\r\n{metaDataString}");
            }
            return metaDataContent;
        }

        public void Enable(params IMetaDataContent[] metaData)
        {
            return;
        }

        public IList<MetaDataExportContent> Export(params IMetaDataContent[] metaDataList)
        {
            return new List<MetaDataExportContent>();
        }

        public IMetaDataContent GetMetaDataContent(string metaDataId)
        {
            return menuLogic.GetMenu(metaDataId);
        }

        public void Import(IList<MetaDataExportContent> contents, MetaDataImportStrategy importStrategy)
        {
            try
            {
                foreach (var exportContent in contents)
                {
                    var parameter = new Dictionary<string, string>();
                    SGHttpClient httpClient = new SGHttpClient(true);
                    if (importStrategy == MetaDataImportStrategy.Delete)
                    {
                        var fasMenu = menuLogic.GetMenu(exportContent.MetaDataId);
                        if (fasMenu == null)
                            continue;
                        menuLogic.DeleteMenu(exportContent.MetaDataId);
                        parameter.Add("fasMenu", JsonConvert.SerializeObject(fasMenu));
                        parameter.Add("fasPage", null);
                        parameter.Add("publishType", "deleteMenu");
                    }
                    else
                    {
                        var fasMenu = JsonConvert.DeserializeObject<FasMenu>(exportContent.Content);
                        if (menuLogic.IsExist(fasMenu.ID))
                        {
                            menuLogic.UpdateMenu(fasMenu);
                        }
                        else
                        {
                            menuLogic.AddMenu(fasMenu);
                        }
                        parameter.Add("fasMenu", JsonConvert.SerializeObject(fasMenu));
                        parameter.Add("fasPage", JsonConvert.SerializeObject(fasMenu.PageMetaData));
                        parameter.Add("publishType", "updateMenu");
                    }
                    var response = httpClient.PostMainIDCEx<object>("FASRM-PublishMenu", parameter, new Dictionary<string, string> { { "fasdevappid", "fascommon" } }, null, 60, 1);
                    if (response.state == "0")
                        throw new FasException(FasMenuExceptionCode.ImportFailed, $"发布到路由表失败,msg:{response.errmsg}");
                    if (!string.IsNullOrEmpty(Convert.ToString(response.data)))
                        throw new FasException(FasMenuExceptionCode.ImportFailed, $"发布到路由表失败,msg:{response.data}");
                }
            }
            catch (Exception e)
            {
                throw new FasException(FasMenuExceptionCode.ImportFailed, "导入FasMenu元数据失败", e);
            }
        }


        public void Release(IMetaDataContent metaData, ReleaseStrategy releaseStrategy)
        {
            return;
        }

        public void Save(IMetaDataContent metaData)
        {

        }

        public string SerializeObject(IMetaDataContent metadata, MetadataSerializeType serializeType)
        {
            if (metadata == null) return string.Empty;
            try
            {
                switch (serializeType)
                {
                    case MetadataSerializeType.XML:
                        var serializer = new XmlSerializer(typeof(PageMetaData));
                        using (var stringWriter = new StringWriter())
                        {
                            using (var writer = XmlWriter.Create(stringWriter))
                            {
                                serializer.Serialize(writer, metadata);
                                return stringWriter.ToString();
                            }
                        }

                    case MetadataSerializeType.JSON:
                    default:
                        return JsonConvert.SerializeObject(metadata);
                }
            }
            catch (Exception e)
            {
                throw new FasException(PageExceptionCode.SerializeFailed, "Page元数据序列化失败" + e.ToString());
            }
        }

        public void Update(IMetaDataContent metaData)
        {

        }

        public ValidateResult Validate(IMetaDataContent metaData)
        {
            return new ValidateResult();
        }
        public List<MetaDataDependency> GetMetaDataDependencys(IMetaDataContent metaDataContent)
        {
            return new List<MetaDataDependency>();
        }


        public MetaDataUpdateSet GetMetaDataUpdateSet(IMetaDataContent oldMetaData, IMetaDataContent newMetaData)
        {
            return null;
        }

        public MetaUpdateResult UpdateDependencyMetaData(IMetaDataContent metaDataContent, MetaDataUpdateSet updateSet)
        {
            return null;
        }

        public IRefSchemaEntity BuildRefSchema(IMetaDataContent metaDataContent)
        {
            return null;
        }

        public IRefSchemaEntity DeserializeRefSchemaEntity(string schemaEntityJson)
        {
            return null;
        }
        public IEnumerable<Entity.Term> BuildTerms(IMetaDataContent metaDataContent, IEnumerable<Entity.Term> terms = null)
        {
            return new List<Entity.Term>();
        }
        public ValidateResult CompatibleValidate(IMetaDataContent metaData, IMetaDataContent oldMetaData)
        {
            return new ValidateResult { state = "1" };
        }

        public override MetaGenerateCodeResult GenerateCode(IMetaDataContent metadata, bool isInternational)
        {
            throw new NotImplementedException();
        }
    }
}
